﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace FBGraph
{
    /// <summary>A wrapper for paged collections of data that are returned by the Graph API.</summary>
    /// <typeparam name="TItem">The type of item in the collection.</typeparam>
    [DataContract(Name = "pagedResult")]
    public class PagedResult<TItem> : IFBGraphResult
    {
        /// <summary>Gets or sets the array of <typeparamref name="TItem" /> objects.</summary>
        [DataMember(Name = "data")]
        public TItem[] Data { get; set; }

        [DataMember(Name = "paging")]
        internal PagingContainer Paging { get; set; }

        /// <summary>Gets the Graph API url for querying the previous page of items.</summary>
        [IgnoreDataMember]
        public Uri PreviousPageUrl { get { return this.Paging.Previous; } }

        /// <summary>Gets the Graph API url for querying the next page of items.</summary>
        [IgnoreDataMember]
        public Uri NextPageUrl { get { return this.Paging.Next; } }

        /// <summary>A wrapper for paging information provided by <see cref="PagedResult{TItem}" />.</summary>
        [DataContract(Name = "pagingContainer")]
        internal class PagingContainer
        {
            [DataMember(Name = "previous")]
            public Uri Previous { get; set; }

            [DataMember(Name = "next")]
            public Uri Next { get; set; }
        }
        /// <summary>Returns an enumerator that iterates through the collection.</summary>
        /// <returns>An enumerator that iterates through the collection.</returns>
        public IEnumerator<TItem> GetEnumerator()
        {
            return ((IEnumerable<TItem>)Data).GetEnumerator();
        }

        #region [ IFBGraphResult Members ]

        /// <summary>Gets or sets a <see cref="Boolean" /> value representing whether the object has been populated.</summary>
        protected virtual Boolean IsReady { get; set; }
        Boolean IFBGraphResult.IsReady
        {
            get { return this.IsReady; }
            set { this.IsReady = value; }
        }

        void IFBGraphResult.UpdateFrom(IFBGraphResult other)
        {
            var that = other as PagedResult<TItem>;
            if (that == null) return;
            else
            {
                this.Data = that.Data;
                this.Paging = that.Paging;
                this.IsReady = true;
            }
        }

        #endregion
    }
}